package main

import "fmt"
import "net"
import "errors"
import "math"
import "strings"
import "strconv"
import "sort"
import "unicode"

func GetDatas() (int, int) {
	return 100, 200
}
// 遍历字符串
func traversalString() {
	s := "hello沙河"
	for i := 0; i < len(s); i++ { //byte
		fmt.Printf("%v(%c) ", s[i], s[i])
	}
	fmt.Println()
	for _, r := range s { //rune
		fmt.Printf("%v(%c) ", r, r)
	}
	fmt.Println()
}
func changeString() {
	s1 := "big"
	// 强制类型转换
	byteS1 := []byte(s1)
	byteS1[0] = 'p'
	fmt.Println(string(byteS1))

	s2 := "白萝卜"
	runeS2 := []rune(s2)
	runeS2[0] = '红'
	fmt.Println(string(runeS2))
}
func test1() {
	t1 := 1
	t2 := 10.0
	fmt.Printf("%T ", t1)
	fmt.Printf("%T ", t2)
	t3 := "hello落寞的鱼总"
	arr3 := []rune(t3)
	num := 0
	for _, r := range arr3 {
		fmt.Println(r)
		if (r > 'z') {
			num++
		}
	}
	fmt.Println(num)
}
func test2() { // 找到只出现一次的数字
	arr := []string {"1","2","3","4","5","2","1","3","5"}
  str := strings.Join(arr, "")
	fmt.Println("test2========")
	for i, _ := range arr {
		if(strings.Index(str,arr[i]) == strings.LastIndex(str,arr[i])) {
			fmt.Println("只出现一次的数字:",arr[i])
		}
	}
}
func subTest2() { // 自己与自己异或为0 数组所有元素异或的值就是只出现一次的元素的值
	var nums  = []int {1,2,3,4,5,2,1,3,5}
	i := 0
	for j := 0; j < len(nums); j ++ {
		i = i ^ nums[j]
	}
	fmt.Println("subTest2: ",i)
}
func ifDemo1() {
	score := 65
	if score >= 90 {
		fmt.Println("A")
	} else if score > 75 {
		fmt.Println("B")
	} else {
		fmt.Println("C")
	}
	fmt.Println(score)
}
func ifDemo2() {
	if score := 65; score >= 90 {
		fmt.Println("A")
	} else if score > 75 {
		fmt.Println("B")
	} else {
		fmt.Println("C")
	}
}
func forDemo() {
	total := 0;
	for i := 0; i <= 100; i++ {
		total += i;
	}
	fmt.Println(total)
}
func gotoDemo2() {
	for i := 0; i < 10; i++ {
		for j := 0; j < 10; j++ {
			if j == 2 {
				// 设置退出标签
				goto breakTag
			}
			fmt.Printf("%v-%v\n", i, j)
		}
	}
	return
	// 标签
breakTag:
	fmt.Println("结束for循环")
}
func breakDemo1() { //结束循环代码块
	BREAKDEMO1:
		for i := 0; i < 10; i++ {
			for j := 0; j < 10; j++ {
				if j == 2 {
					break BREAKDEMO1
				}
				fmt.Printf("%v-%v\n", i, j)
			}
		}
	  fmt.Println("...")
}
func continueDemo() {
	forloop1:
		for i := 0; i < 5; i++ {
			// forloop2:
			for j := 0; j < 5; j++ {
				if i == 2 && j == 2 {
					continue forloop1
				}
				fmt.Printf("%v-%v\n", i, j)
			}
		}
}
func jiujiu() {
	newjiujiu:
		for i := 1; i <= 9; i++ {
			for j := 1; j <= 9; j++ {
				if(i >= j) {
					fmt.Printf(strconv.Itoa(j) + "*" + strconv.Itoa(i) + "=" + strconv.Itoa(i * j) + " ")
				} else {
					fmt.Println("")
					continue newjiujiu
				}
			}
		}
}
func errorTest() {
	fmt.Println("========")
	var a [3]string
	var b [4]int
	fmt.Println(a[2])
	fmt.Println(b[3])
	fmt.Printf("数组类型%T\n", a)
	fmt.Printf("数组类型%T\n", b)
	var c = [...]bool {1: true, 4: true}
	fmt.Println("索引值初始化", c)
	for i := 0; i < len(c); i++ {
		if (c[i]) {
			fmt.Print("真")
		} else {
			fmt.Print("假")
		}
	}
	fmt.Println("")
	for index, value := range c {
		fmt.Println(index, value)
	}

	d := [3][2]string {
		{"烟台", "济南"},
		{"朝阳", "海淀"},
		{"长沙", "武汉"},
	}
	fmt.Println("二维数组", d)
	fmt.Println("遍历二维数组")
	for i := 0; i < len(d); i++ {
		for j := 0; j < len(d[i]); j++ {
			fmt.Println(d[i][j])
		}
	}
	for _, val1 := range d {
		for index2, val2 := range val1 {
			fmt.Printf("%d%s\t",index2, val2)
		}
		fmt.Println()
	}
}
func sliceFunc() {
	a := [...]int{1,2,3,4,5}
	s := a[1:4]
	fmt.Printf("s: %v\t, len: %v\t, cap: %v\t", s, len(s), cap(s))
	s1 := a[:]
	s2 := a[:3]
	s3 := a[1:]
	fmt.Println(s1,cap(s1),s2,cap(s2),s3,cap(s3),a,cap(a))
}
func makeSlice() {
	a := make([]int, 3, 10)
	fmt.Println(a)
	fmt.Println(len(a))
	fmt.Println(cap(a))
}
func sliceCp() {
	a := [3]int {1,2,3}
	s1 := a[:2]
	s2 := a[1:]
	s1[1] = 199
	fmt.Println("======")
	fmt.Println(s1,s2)
}
func sliceFor() {
	s := []int{1, 3, 5}
	for i := 0; i < len(s); i++ {
		fmt.Println(i, s[i])
	}
	for index, value := range s {
		fmt.Println(index, value)
	}
}
func sliceAppend() {
	a := [...]int {1,3,5}
	s := a[:]
	s = append(s, 7)
	fmt.Println(s)
	s = append(s, 9 ,11)
	fmt.Println(s)
	s = append(s, s[3])
	fmt.Println(s)
	a1 := []int {3}
	s1 := a1[:]
	s = append(s, s1...)
	fmt.Println(s)
}
func sliceCopy() {
	// copy完后两个切片指向的不是同一块内存地址
	s1 := []int{1,2,3,4,5}
	s2 := make([]int, 5, 5)
	copy(s2, s1)
	fmt.Println(s1, s2)
	s1[0] = 100
	fmt.Println(s1, s2)
	s1 = append(s1[1:])
	fmt.Println(s1, s2)
}
func sliceTest1() {
	var a = make([]string, 5, 10)
	for i := 0; i < 10; i++ {
		a = append(a, fmt.Sprintf("%v", i))
	}
	fmt.Println(a)
	// [0 0 0 0 0 0 1 ... 9]
}
func sliceSort() {
	a := []int {6,5,11,66,2321,34}
	fmt.Println(a)
	intList := sort.IntSlice(a)
	fmt.Println(intList)
	sort.Sort(intList)
	fmt.Println(intList)
	// sort.Sort(a)
	// fmt.Println(a)
}
func mapFunc() {
	scoreMap := make(map[string]int, 50)
	scoreMap["张三"] = 0
	scoreMap["小明"] = 100
	fmt.Println(scoreMap)
	userMap := map[string]string{
		"username": "admin",
		"password": "admin1234",
	}
	fmt.Println(userMap)
	val, ok := scoreMap["张三"]
	if ok {
		fmt.Println(val)
	} else {
		fmt.Println("查无此人")
	}
	val1, flg := scoreMap["zhangsan"]
	if flg {
		fmt.Println(val1)
	} else {
		fmt.Println("查无此人")
	}
}
func mapFor() {
	newMap := make(map[string]int, 50)
	newMap["zs"] = 90
	newMap["ls"] = 80
	newMap["ww"] = 70
	newMap["tt"] = 100
	delete(newMap, "tt")
	for k,v := range newMap {
		fmt.Println(k, v)
	}
}
func mapTest1() {
	// 计算一句话中每个单词出现的频率(带标点)
	s := "Hello, how do you do?"
	fmt.Println(len(s))
	s1 := make([]string, 0 ,50) 
	newMap := make(map[string]int, 20)
	word := ""
	for index,c := range s{
		if unicode.IsLetter(c) {
			word = fmt.Sprintf("%s%c", word, c)
		} else {
			if c == ' ' {
			  s1 = append(s1, word)
				word = ""
			}
		}
		if index == len(s) - 1 {
			s1 = append(s1, word)
		}
	}
	fmt.Println(s1)
	for _,val := range s1 {
		newMap[val]++
	}
	fmt.Println(newMap)
}
func mapTest2() {
	type Map map[string][]int
	m := make(Map)
	s := []int{1, 2}
	s = append(s, 3, 4)
	fmt.Println("========")
	fmt.Printf("%+v\n", s)
	m["q1mi"] = s
	s = append(s[:1], s[3:]...)
	fmt.Printf("%+v\n", m["q1mi"])
	fmt.Printf("%+v\n", s)
	fmt.Printf("%+v\n", m["q1mi"])
}
func intAdd(x int, y int) int {
	return x + y
}
func intSub(x int, y int) int {
	return x - y
}
func doSomeThing(s string) (func(int, int) int, error) {
	switch s {
	case "+":
		return intAdd, nil
	case "-":
		return intSub, nil
	default:
		err := errors.New("无法识别的操作符")
		return nil, err
	}
}
func main() {
	var (
		varInt int
		varStr string
		varBool bool
		varInt8 int8
		varInt16 int16
		varuint uint
		varByte byte
		varFloat float32 = 0.17
		varcomp complex64
	)
	conn,err := net.Dial("tcp", "127.0.0.1:3000")
	a, b := 100, 200
	fmt.Println(a, b)
	a, b = b, a
	fmt.Println(a, b)
	fmt.Println("Hello World!")
	fmt.Println(varInt)
	fmt.Println(varStr)
	fmt.Println(varBool)
	fmt.Println(varInt8)
	fmt.Println(varInt16)
	fmt.Println(varuint)
	fmt.Println(varByte)
	fmt.Println(varFloat)
	fmt.Println(varcomp)
	fmt.Println("===============")
	fmt.Println(conn)
	fmt.Println(err)
	num1, _ := GetDatas()
	_, num2 := GetDatas()
	
	fmt.Println(num1, num2)
	fmt.Printf("a = %d, b = %d, num1 = %d\n", a, b, num1)
	fmt.Println("===============")
	fmt.Println(math.MaxFloat32)
	fmt.Println(math.MaxFloat64)
	const plk = 6.666e03
	const ago = 6.0221e-08
	fmt.Println(int(plk))
	fmt.Println(float64(ago))
	var comp1 complex64 = complex(2, 3)
	var comp2 complex64 = complex(5, 7)
	fmt.Println(comp1 * comp2)
	fmt.Println(comp1 / comp2)
	fmt.Println(real(comp1 / comp2),imag(comp1 / comp2))
	fmt.Println("str := \"c:\\Code\\lesson1\\go.exe\"")
	fmt.Println("a \" b")
	s1 := `first
	mid
	\n
	last`
	fmt.Println(s1)
	s2 := "lksdjfll\\a\"\"###siqkj三等奖42"
	fmt.Println(s2)
	fmt.Println(len(s2))
	fmt.Println(s2 + "二等奖")
	fmt.Println(strings.Split(s2, "\\"))  // 打印的是切片
	fmt.Println()
	fmt.Println(strings.Contains(s2,"ksd1"))
	s3 := "www.qq.com"
	fmt.Println(strings.HasPrefix(s3,"www"))
	fmt.Println(strings.HasSuffix(s3,"cn"))
	fmt.Println(strings.Index(s3,"."))
	fmt.Println(strings.LastIndex(s3,"."))
	arr1 :=[]string {"1","2","3"}
	fmt.Println(strings.Join(arr1,"s"))
	// uint8(byte) 代表ASCII码一个字符
	// rune类型(int32) 代表一个utf-8字符
	traversalString()
	fmt.Println(strings.Join(arr1,"s"))
	s4 := "更改字符串"
	s4 = "b新字符串"
	news4 := []rune(s4)
	news4[0] = 'a'
	fmt.Println(len(news4))
	fmt.Println(string(news4))
	fmt.Println(s4)
	changeString()
	test1()
	test2()
	subTest2()
	forDemo()
	gotoDemo2()
	breakDemo1()
	continueDemo()
	jiujiu()
	errorTest()
	sliceFunc()
	makeSlice()
	sliceCp()
	sliceFor()
	sliceAppend()
	sliceCopy()
	sliceTest1()
	sliceSort()
	mapFunc()
	mapFor()
	mapTest1()
	mapTest2()
	sum := intAdd(233, 998)
	fmt.Println(sum)
	newFunc, _ := doSomeThing("+")
	fmt.Println(newFunc(2,3))
	newFunc1, _ := doSomeThing("-")
	fmt.Println(newFunc1(5,3))
	_, errStr := doSomeThing("*")
	fmt.Println(errStr)
}